home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Format Collection 21
/
PC Format CD-ROM Collection 21 (1995-12)(Future Publishing)(GB)[issue 51].iso
/
resource
/
show'em.poc
< prev
next >
Wrap
Text File
|
1992-10-15
|
78KB
|
3,334 lines
// Show'em.poc - A program which makes fancy bulleted text slide presentations
// out of simple text files. This POCO routine can be used with Autodesk's
// Animator Pro Version 1.3 or higher.
//
// Copyright 1992 Michael Edmonds and Dancing Flame
// This file may be copied, used, and modified by legal license holders of
// the Autodesk Animator Pro.
// Need to make sure we're running the right version of Animator Pro.
#if __POCO__ < 181
#error "You must upgrade to Animator Pro 1.3 or later to run this program"
#endif
#include <stdio.h>
#include <ctype.h>
#include <optics.h>
//-------------------------------------------------------------------------
// Defines and stuff you know and love
//-------------------------------------------------------------------------
#define TRUE 1
#define FALSE 0
#define Success 0
#define EOS 0
#define ESCAPE_KEY 0x1b
#define PIXEL_SIZE 1
/* Flags for disabling buttons on a QmenuWithFlags() */
#define QMF_DISABLED (1<<0)
#define QMF_ASTERISK (1<<1)
static char *off_on[2] = {"OFF", "ON"};
/* A little macro that prints out the line number. Useful for debugging. */
#define TBOX Qtext("%s %d", __FILE__,__LINE__ );
typedef struct
/* A color. R(ed), G(reen), B(lue) go from 0 to 255 */
{
int r,g,b;
} RGB;
typedef struct
/* Two dimensional point. */
{
int x,y;
} XY;
//-------------------------------------------------------------------------
// Persistant Variables
// (ones which persist between runs of program.)
//-------------------------------------------------------------------------
#define UNTITLED_TEXT "untitled.txt"
Boolean text_changed = FALSE;
Boolean text_named = FALSE;
char text_file_name[PATH_SIZE] = UNTITLED_TEXT;
static char pn_text_changed[] = "show'em.text_changed";
static char pn_text_named[] = "show'em.text_named";
static char pn_text_file_name[] = "show'em.text_file_name";
Boolean get_persistant_boolean(char *var_name, Boolean default_val)
/*
* This will return the TRUE if the value of var_name is "TRUE", else
* FALSE. If the var_name does not exist returns default_val.
*/
{
char buf[10];
if (GlobalVarGet(var_name, buf) >= Success)
{
return (stricmp(buf, "TRUE") == 0);
}
else
return default_val;
}
Errcode save_persistant_boolean(char *var_name, Boolean val)
{
if (val)
return GlobalVarSet(var_name, "TRUE");
else
return GlobalVarSet(var_name, "FALSE");
}
void load_persistant()
/*
* Load in all persistant variables.
*/
{
text_changed = get_persistant_boolean(pn_text_changed, text_changed);
text_named = get_persistant_boolean(pn_text_named, text_named);
GlobalVarGet(pn_text_file_name, text_file_name);
}
void save_persistant()
{
save_persistant_boolean(pn_text_changed, text_changed);
save_persistant_boolean(pn_text_named, text_named);
GlobalVarSet(pn_text_file_name, text_file_name);
}
//-------------------------------------------------------------------------
// Global Variables
//-------------------------------------------------------------------------
char persistant_text[] = "=:show'em.txt";
char persistant_style[] = "=:show'em.sty";
int slide_width, slide_height;
int shadow_xoff, shadow_yoff;
FILE *script;
//-------------------------------------------------------------------------
// Menu Definitions
//-------------------------------------------------------------------------
static char mm_header[] = "Show'em 1.0";
static char *mm_choices[] =
{
"Help",
"Create Slide Show",
"Set Slide Style",
"Exit",
};
static enum { MAIN_EXIT, MAIN_HELP, MAIN_CREATE, MAIN_FORMAT};
static char mm_help1[] =
"Show'em creates a slide presentation from simple text input. "
"All slides in a presentation share a background, logo, title, and "
"bullet style. You can specify the fonts, colors, and styles with "
"the Set Slide Style menu. Then, from the Create Slide Show menu, "
"you define the text, preview the slides, and render them. "
;
static char mm_help2[] =
"Show'em creates a numbered series of pictures, animated images, "
"Autodesk Animator Pro Player scripts, and a batch file to play the "
"scripts. To present a slide show in its final form, select "
"Create Slide Show and then Render Slides. Then, exit Animator Pro "
"and use the batch file created with Show'em to run it. The batch file "
"uses Aniplay and the scripts and images produced by Show'em to run "
"your slide show. "
;
static char *mm_help[] = {mm_help1, mm_help2};
static char css_header[] = "Create Slide Show";
static char *css_choices[] =
{
"Help",
"Edit Text",
"Load Text",
"Save Text",
"New Text",
"Preview",
"Render Slides",
"Return",
};
static enum {CSS_EXIT, CSS_HELP, CSS_EDIT, CSS_LOAD, CSS_SAVE, CSS_NEW
, CSS_PREVIEW, CSS_RENDER};
static char *css_help[] = {
"To create a slide show, you define the text for each slide. You can "
"load the slide text from an ascii text file or you can enter the text "
"directly by selecting Edit Text. Each paragraph of text (separated "
"by a blank line) creates one slide. The first line of each paragraph "
"becomes the title. Subsequent lines become bullet items."
,
"There are also a few commands you can put in the text that allow "
"you to (1) eliminate the pause between items in an animated slide; "
"(2) include clips like business charts, AutoCAD slides, and scanned "
"images right on your slides; (3) show any animation or picture within "
"your presentation; and (4) place an interactive demo in the middle of "
"your presentation and return to your presentation automatically. "
,
"You can insert the following commands in your input text. "
"They must be in lower case and on a line by themselves. "
"\n\n"
"\"-nopause\" Suppress the pause that Show'em puts between animated "
"items on a slide. "
"\n\n"
"\"-i ...\" Follow this by the file name of a cel you want pasted on a slide. "
"\n\n"
"\"-x ...\" Follow this with any Animator Pro Player script "
"command. This must be in its own single line paragraph. "
"\n\n"
"\"-b ...\" Follow this with any valid DOS command. "
"This must be in its own single line paragraph. "
};
static char ssf_header[] = "Set Slide Style";
static char *ssf_choices[] =
{
"Help",
"Title",
"Items",
"Bullet",
"Background",
"Logo",
"Output",
"Load Style",
"Save Style",
"Return",
};
static enum {SSF_EXIT, SSF_HELP, SSF_TITLE, SSF_ITEMS, SSF_BULLET
, SSF_BACKGROUND, SSF_LOGO, SSF_OUTPUT, SSF_LOAD, SSF_SAVE};
static char ssf_help[] =
"This menu controls the slide style.\n"
"\n"
"Title - Set the title color, font,\n"
" position, and justification.\n"
"Items - Set the item color and font.\n"
"Bullet - Set bullet color, use a circle\n"
" bullet, load a cel to use as the\n"
" bullet, or use no bullet.\n"
"Background - Set the background color,\n"
" solid or gradient, or load an image\n"
" to use as background.\n"
"Logo - Load a cel to use as logo,\n"
" position it, or don't use a logo.\n"
"Output - Set slides as still images or\n"
" animated with scrolling or fading;\n"
" turn antialiasing on and off; turn\n"
" safe titling on and off; get help.\n"
"Load Style - Load a style file.\n"
"Save Style - Save a style file.\n"
;
static char title_header[] = "Title Style";
static char *title_choices[] =
{
"Title Color",
"Title Font",
"Position Title",
"Justify Title",
"Return",
};
static enum {TITLE_EXIT, TITLE_COLOR, TITLE_FONT, TITLE_POS, TITLE_JUST};
static char title_just_header[] = "Title Justification";
static char *title_just_choices[] =
{
"Left",
"Right",
"Center",
"Fill",
"Return",
};
static char item_header[] = "Item Style";
static char *item_choices[] =
{
"Item Color",
"Item Font",
"Return",
};
static enum {ITEM_EXIT, ITEM_COLOR, ITEM_FONT};
static char bullet_header[] = "Set Bullet Image";
static char *bullet_choices[] =
{
"Set Bullet Color",
"Use a Circle for Bullets",
"Load a Cel for Bullets",
"Don't Use Bullets",
"Return",
};
static enum {BULLET_EXIT
, BULLET_COLOR, BULLET_CIRCLE, BULLET_USE_CEL, BULLET_NONE};
static char background_header[] = "Set Background Image";
static char *background_choices[] =
{
"Set Background Color",
"Use a Solid Background",
"Use a Gradient Background",
"Load Background Image",
"Return",
};
static enum {BACKGROUND_EXIT, BACKGROUND_GET_COLOR
, BACKGROUND_SOLID, BACKGROUND_GRADIENT, BACKGROUND_USE_PIC};
static char logo_header[] = "Logo Style";
static char *logo_choices[] =
{
"Load a Logo Cel",
"Position Logo Cel",
"Don't Use a Logo",
"Return",
};
static enum {LOGO_EXIT, LOGO_USE_CEL, LOGO_POSITION, LOGO_NONE};
static char out_header[] = "Set Output Style";
static char *out_choices[] =
{
"Help",
"Still Images",
"Scrolling",
"Fading",
"Anti-aliasing",
"Safe Titling",
"Preview",
"Return",
};
static enum {OUT_EXIT, OUT_HELP
, OUT_STILL, OUT_SCROLL, OUT_FADE, OUT_ANTIALIAS, OUT_SAFE_TITLE, OUT_PREVIEW};
static char out_help1[] =
"The output menu contains these options:\n"
"\n"
"Still Images - The bullet items are not\n"
" animated. Slides are written as \n"
" single frame flic files.\n"
"Scrolling - The bullet items are\n"
" animated, scrolling onto the screen\n"
" from the right. The slides are saved\n"
" in a combination of Flic files.\n"
"Fading - The bullet items are animated,\n"
" fading onto the screen. The slides\n"
" are saved in a combination of Flic\n"
" files.\n"
"Anti-aliasing - Toggles smoothing of\n"
" edges on and off. When on the images\n"
" render slower but look a bit better.\n"
"Safe Titling - Toggles the reduction of\n"
" the slide size on the screen so your\n"
" titles are fully visible when shown\n"
" on a TV.\n"
;
//-------------------------------------------------------------------------
// Some Utility Routines maybe we'll use in another poco program too
//-------------------------------------------------------------------------
Boolean ignore_changes()
/*
* If have made changes to flic make sure it's ok to ignore them.
*/
{
int changes;
static char replace_changes_prompt[]
= "Okay to discard current flic?\n"
"(You have unsaved changes)";
if ((changes = GetChangeCount()) != 0)
return Qquestion(replace_changes_prompt);
else
return TRUE;
}
Boolean overwrite_ok(char *file_name)
/*
* If file exists make sure it's ok to overwrite it.
*/
{
if (DosExists(file_name))
return Qquestion("Write over old %s", file_name);
else
return TRUE;
}
FILE *must_open(char *file_name, char *mode)
/*
* Open file to read. Complain if can't.
*/
{
FILE *f;
char c = tolower(mode[0]);
if ((f = fopen(file_name, mode)) == NULL)
{
if (c == 'w')
Qtext("Can't create %s, sorry\n", file_name);
else
Qtext("Can't find %s, sorry\n", file_name);
}
return f;
}
void *need_memory(unsigned size)
/*
* Request memory. Squawk if can't get it.
*/
{
void *pt;
if ((pt = malloc(size)) == NULL)
Qtext("Couldn't find %d bytes of free memory, sorry", size);
return pt;
}
Boolean copy_file(char *source, char *dest)
/*
* Copy one file to another.
*/
{
FILE *s, *d;
int c;
Boolean ok = FALSE;
if ((s = must_open(source, "rb")) != NULL)
{
if ((d = must_open(dest, "wb")) != NULL)
{
while ((c = getc(s)) != EOF)
{
if (putc(c, d) == EOF)
{
Qtext("Couldn't copy %s to %s, %s truncated"
, source, dest, dest);
break;
}
}
fclose(d);
}
fclose(s);
ok = TRUE;
}
return ok;
}
char *skip_space(char *pt)
/*
* Return first non-space character in string, or NULL if all spaces
* until end.
*/
{
if (pt == NULL)
return NULL;
while (isspace(*pt))
++pt;
if (*pt == EOS)
return(NULL);
return(pt);
}
char *skip_to_space(char *pt)
/*
* Return first space character (or EOS) character in string.
*/
{
char c;
for (;;)
{
c = *pt;
if (isspace(c) || c == EOS)
break;
++pt;
}
return(pt);
}
void file_name_only(char *path, char *file_only)
/*
* Extract just the file name from a path. That is
* convert C:\ANI\DUCKY.FLI to DUCKY.FLI
*/
{
char dev[4], dir[70], file[10], suff[5]; /* FNsplit/merge stuff */
fnsplit(path,dev,dir,file,suff);
sprintf(file_only, "%s%s", file, suff);
}
void translate_to_rgb(int index, RGB *color)
/*
* Look up color map index and store it in color
*/
{
GetColorMap(index, &color->r, &color->g, &color->b);
}
void multi_screen_help(char *screens[], int screen_count)
/*
* Put up multiple screens of help. Pass in an array of strings, one
* for each string. This will put up a series of dialogs, one for each
* screen, and let the user navigate back and forth between them.
* Returns when user selects "done" or right clicks out.
*/
{
static char prev_string[] = "Previous";
static char next_string[] = "Next";
static char done_string[] = "Done";
static char *done[1] = {done_string};
static char *done_next[2] = {done_string, next_string};
static char *prev_done_next[3] = {prev_string, done_string, next_string};
static char *prev_done[2] = {prev_string, done_string};
if (screen_count == 1)
Qchoice(done, Array_els(done), screens[0]);
else
{
int screen_index = 0;
int choice;
for (;;)
{
if (screen_index == 0)
{
choice = Qchoice(done_next, Array_els(done_next)
, screens[screen_index]);
switch (choice)
{
case 2:
++screen_index;
break;
default:
return;
}
}
else if (screen_index == screen_count - 1)
{
choice = Qchoice(prev_done, Array_els(prev_done)
, screens[screen_index]);
switch (choice)
{
case 1:
--screen_index;
break;
default:
return;
}
}
else
{
choice = Qchoice(prev_done_next, Array_els(prev_done_next)
, screens[screen_index]);
switch (choice)
{
case 1:
--screen_index;
break;
case 3:
++screen_index;
break;
default:
return;
}
}
}
}
}
//-------------------------------------------------------------------------
// Some font related stuff.
//-------------------------------------------------------------------------
void full_font_name(char *name, char *path)
/*
* This removes any existing directory info from name and replaces it
* with the current font directory. The result is in path.
*/
{
char name_only[PATH_SIZE];
GetFontDir(path);
file_name_only(name, name_only);
strcat(path, name_only);
}
ErrCode load_font(char *name)
/*
* Load font, looking if necessary in the font directory for it.
* Also keep last font name used for reference to prevent unnecessary
* reloading of font.
*/
{
char fdir[80];
ErrCode err;
static char last_font_name[PATH_SIZE];
if (strcmp(last_font_name, name) == 0)
return Success;
if ((err = LoadFont(name)) < Success)
{
full_font_name(name, fdir);
err = Qerror(LoadFont(fdir), "Loading font %s", fdir);
}
strcpy(last_font_name, name);
return err;
}
typedef struct
/*
* Holds all pertinant info about type face - font size spacing data.
*/
{
char name[PATH_SIZE];
int size, spacing, leading;
} Font_style;
void get_font_style(Font_style *fs)
/*
* Get current status of font into Font_style
*/
{
GetFontName(fs->name);
fs->spacing = GetFontSpacing();
fs->leading = GetFontLeading();
fs->size = FontHeight() - fs->leading;
}
Boolean set_font_style(Font_style *fs)
/*
* Set font from Font_style
*/
{
if (load_font(fs->name) < Success)
return FALSE;
ScaleFont(fs->size);
SetFontSpacing(fs->spacing);
SetFontLeading(fs->leading);
return TRUE;
}
//-------------------------------------------------------------------------
// Some stuff to read a file a line at a time and report errors.
//-------------------------------------------------------------------------
typedef struct
/* This structure keeps track of where we are in a file. */
{
FILE *f;
char *file_name;
char *line_buf;
int buf_size;
int current_line;
char x_call[256];
char bat_call[256];
} Line_file;
Boolean line_file_open(Line_file *f, char *file_name, char *buf, int buf_size)
/*
* Open up a file and set up structure to read it one line at a time
*/
{
if ((f->f = must_open(file_name, "r")) == NULL)
return FALSE;
f->file_name = file_name;
f->line_buf = buf;
f->buf_size = buf_size;
f->current_line = 0;
strcpy(f->x_call, "none");
strcpy(f->bat_call, "none");
return TRUE;
}
void line_file_close(Line_file *f)
/*
* Close a line file.
*/
{
if (f->f != NULL)
{
fclose(f->f);
f->f = NULL;
}
}
Boolean read_line(Line_file *file)
/*
* Read a line from file. Return FALSE at EOF.
*/
{
char *pt;
pt = file->line_buf;
pt = fgets(pt, file->buf_size, file->f);
++file->current_line;
return (pt != NULL);
}
Boolean must_read_line(Line_file *file)
/*
* Read a line from file
* complain if it's not there.
*/
{
if (!read_line(file))
{
Qtext("%s %d: file too short\n"
, file->file_name, file->current_line);
return FALSE;
}
return TRUE;
}
void expecting_got(Line_file *file, char *expecting, char *got)
/*
* Print "expecting/got" error message
*/
{
if (got == NULL)
got = "(NULL)";
if (skip_space(got) == NULL)
got = "<cr>";
Qtext("%s line %d:\nExpecting %s got %s"
, file->file_name, file->current_line
, expecting, got);
}
Boolean next_string(Line_file *file, char **input, char *result, int max_size)
/*
* Get next space separated token from input (and advance input).
*/
{
char *start;
char *end;
int size;
if ((start = skip_space(*input)) == NULL)
return FALSE;
end = skip_to_space(start);
size = end - start;
if (size >= max_size)
{
Qtext("%s %d:\nToken \"%s\" too long.\nCan only handle %d characters\n"
, file->file_name, file->current_line, start, max_size-1);
*input = NULL;
return FALSE;
}
strncpy(result, start, size);
result[size] = EOS;
*input = end;
return TRUE;
}
Boolean next_number(Line_file *file, char **input, int *result)
/*
* Get next number from string.
* Put numerical result in *result. Complain if it's not a number.
*/
{
char num_buf[64]; /* Long enough for any reasonable integer! */
if (!next_string(file, input, num_buf, sizeof(num_buf)))
{
expecting_got(file, "number", "<cr>");
return FALSE;
}
if (!isdigit(num_buf[0]))
{
expecting_got(file, "number", num_buf);
return FALSE;
}
*result = atoi(num_buf);
return TRUE;
}
//-------------------------------------------------------------------------
// Style data structure.
//-------------------------------------------------------------------------
/* Give names to various text justify modes. */
enum Justify {JUST_LEFT, JUST_RIGHT, JUST_CENTER, JUST_FILL};
/* Give names to various animation modes. */
enum AnimMode {AM_STILL, AM_SCROLL, AM_FADE};
typedef struct
/* This guy holds our slide style. */
{
RGB background_color;
char background_image[PATH_SIZE];
RGB title_color;
Font_style title_font;
enum Justify title_justification;
XY title_position;
RGB item_color;
Font_style item_font;
char bullet_image[PATH_SIZE];
RGB bullet_color;
char logo_image[PATH_SIZE];
XY logo_position;
int antialias;
int safe_title;
enum AnimMode animode;
int aniframes;
int anispeed;
} Slide_style;
Slide_style default_style =
{
{100, 40, 255}, /* Background Color. */
"gradient", /* Background Name */
{204, 108, 12,}, /* Title Color */
{"SERB10.FNT", 67, 0, 0}, /* Title font, size, spacing, leading */
JUST_LEFT, /* Title justify */
{0,0,}, /* Title position */
{60, 156, 156,}, /* Item color */
{"SERB08.FNT", 48, 0, 0}, /* Item font, size, spacing, leading */
"circle", /* Bullet name */
{60, 156, 156,}, /* Bullet color */
"none", /* Logo name */
{590, 50}, /* Logo position */
FALSE, /* Antialias toggle*/
FALSE, /* Safe Title toggle
AM_STILL, /* Anim_mode */
0, /* Anim frames */
0, /* Anim speed (milliseconds) */
};
void set_default_style(Slide_style *sf)
/*
* Set style to default.
*/
{
memcpy(sf, &default_style, sizeof(*sf)); /* Do most of the work here. */
full_font_name("SERB10.FNT", sf->title_font.name);
full_font_name("SERB08.FNT", sf->item_font.name);
}
int get_title_width(Slide_style *sf)
/*
* Figure out how wide to make title.
*/
{
int sw,sh;
GetSize(&sw, &sh);
return sw - sf->title_position.x;
}
//-------------------------------------------------------------------------
// Style File Save Routines
//-------------------------------------------------------------------------
static char slide_style_magic[] = "Show'em 1.0 Slide Style:\n";
static Boolean write_rgb(FILE *f, RGB *rgb, char *label)
/*
* Write out RGB triples and label to file.
*/
{
return (fprintf(f, "%d %d %d %s\n", rgb->r, rgb->g, rgb->b, label) > 0);
}
static Boolean write_xy(FILE *f, XY *xy, char *label)
/*
* Write out XY pair and label to file.
*/
{
return (fprintf(f, "%d %d %s\n", xy->x, xy->y, label) > 0);
}
static Boolean write_font_style(FILE *f, Font_style *font, char *label)
/*
* Write out a Font style and label to file.
*/
{
return (fprintf(f, "%s %d %d %d %s Font, Size, Spacing, Leading\n",
font->name, font->size, font->spacing, font->leading, label) > 0);
}
Boolean inside_write_slide_style(Slide_style *sf, FILE *f)
/*
* Write slide style file. Return FALSE if there's a problem.
*/
{
if (fputs(slide_style_magic, f) < Success)
return FALSE;
if (!write_rgb(f, &sf->background_color, "Background Color"))
return FALSE;
if (fprintf(f, "%s Background Image\n", sf->background_image) <= 0)
return FALSE;
if (!write_rgb(f, &sf->title_color, "Title Color"))
return FALSE;
if (!write_font_style(f, &sf->title_font, "Title"))
return FALSE;
if (fprintf(f, "%d Title Justification\n", sf->title_justification) <= 0)
return FALSE;
if (!write_xy(f, &sf->title_position, "Title Position"))
return FALSE;
if (!write_rgb(f, &sf->item_color, "Item Color"))
return FALSE;
if (!write_font_style(f, &sf->item_font, "Item"))
return FALSE;
if (fprintf(f, "%s Bullet Image\n", sf->bullet_image) <= 0)
return FALSE;
if (!write_rgb(f, &sf->bullet_color, "Bullet Color"))
return FALSE;
if (fprintf(f, "%s Logo Image\n", sf->logo_image) <= 0)
return FALSE;
if (!write_xy(f, &sf->logo_position, "Logo Position"))
return FALSE;
if (fprintf(f,"%i AntiAliased Text and Logo (0 = off, 1 = on)\n"
, sf->antialias) <= 0)
return FALSE;
if (fprintf(f,"%i Safe Titling (0 = off, 1 = on)\n"
, sf->safe_title) <= 0)
return FALSE;
if (fprintf(f,"%i %i %i Text Animation Mode\n"
, sf->animode, sf->aniframes, sf->anispeed) <= 0)
return FALSE;
return TRUE;
}
Boolean write_slide_style(Slide_style *sf, char *file_name)
/*
* Open slide style file and write it out. Delete file and complain
* if there's a problem.
*/
{
FILE *f;
Boolean ok = FALSE;
if ((f = must_open(file_name, "w")) != NULL)
{
ok = inside_write_slide_style(sf, f);
fclose(f);
if (!ok)
{
Qtext("Couldn't write slide style to %s, sorry", file_name);
DosDelete(file_name);
}
}
return ok;
}
//-------------------------------------------------------------------------
// Style File Load Routines
//-------------------------------------------------------------------------
Boolean verify_label(Line_file *file, char *buf, char *label)
/*
* Verify that buf contains label.
*/
{
if (stristr(buf, label) == NULL)
{
expecting_got(file, label, buf);
return FALSE;
}
return TRUE;
}
Boolean read_numbers_and_label(Line_file *file
, int *nums, int num_count, char *label)
/*
* Read in a line of form:
* NN ... NN label
* into nums. This is the basis for read_rgb and read_xy.
* Complain and return FALSE if there's a problem.
*/
{
char *buf = file->line_buf;
if (!must_read_line(file))
return FALSE;
while (--num_count >= 0)
{
if (!next_number(file, &buf, nums))
return FALSE;
++nums;
}
return verify_label(file, buf, label);
}
Boolean read_rgb(Line_file *file, RGB *rgb, char *label)
/*
* Read in a line of form:
* NN NN NN label
* into an RGB triple.
* Complain and return FALSE if there's a problem.
*/
{
return read_numbers_and_label(file, (int *)rgb, 3, label);
}
Boolean read_xy(Line_file *file, XY *xy, char *label)
/*
* Read in a line of form:
* NN NN label
* into an XY pair.
* Complain and return FALSE if there's a problem.
*/
{
return read_numbers_and_label(file, (int *)xy, 2, label);
}
Boolean read_int_and_label(Line_file *file, int *result, char *label)
/*
* Read in a line of form:
* NN label
* into *result.
* Complain and return FALSE if there's a problem.
*/
{
return read_numbers_and_label(file, result, 1, label);
}
Boolean read_name_and_label(Line_file *file, char *name, int name_size
, char *label)
/*
* Read in a line of form:
* name label
* into name.
*/
{
char *buf = file->line_buf;
if (!must_read_line(file))
return FALSE;
if (!next_string(file, &buf, name, name_size))
{
expecting_got(file, "a name", "<cr>");
return FALSE;
}
return verify_label(file, buf, label);
}
Boolean read_font_line(Line_file *file, Font_style *fs, char *label)
{
char *buf = file->line_buf;
if (!must_read_line(file))
return FALSE;
if (!next_string(file, &buf, fs->name, sizeof(fs->name)))
{
expecting_got(file, "font name", "<cr>");
return FALSE;
}
if (!next_number(file, &buf, &fs->size))
return FALSE;
if (!next_number(file, &buf, &fs->spacing))
return FALSE;
if (!next_number(file, &buf, &fs->leading))
return FALSE;
return verify_label(file, buf, label);
}
Boolean inside_read_slide_style(Slide_style *sf, Line_file *file)
/*
* Read slide file. Complain if there's a problem.
*/
{
if (!must_read_line(file))
return FALSE;
if (strcmp(file->line_buf, slide_style_magic) != 0)
{
Qtext("%s is not a Show'em Slide Style file.", file->file_name);
return FALSE;
}
if (!read_rgb(file, &sf->background_color, "Background Color"))
return FALSE;
if (!read_name_and_label(file
, sf->background_image, sizeof(sf->background_image)
, "Background Image"))
return FALSE;
if (!read_rgb(file, &sf->title_color, "Title Color"))
return FALSE;
if (!read_font_line(file, &sf->title_font, "Title Font"))
return FALSE;
if (!read_int_and_label(file
, &sf->title_justification, "Title Justification"))
return FALSE;
if (!read_xy(file, &sf->title_position, "Title Position"))
return FALSE;
if (!read_rgb(file, &sf->item_color, "Item Color"))
return FALSE;
if (!read_font_line(file, &sf->item_font, "Item Font"))
return FALSE;
if (!read_name_and_label(file
, sf->bullet_image, sizeof(sf->bullet_image), "Bullet Image"))
return FALSE;
if (!read_rgb(file, &sf->bullet_color, "Bullet Color"))
return FALSE;
if (!read_name_and_label(file
, sf->logo_image, sizeof(sf->logo_image), "Logo Image"))
return FALSE;
if (!read_xy(file, &sf->logo_position, "Logo Position"))
return FALSE;
if (!read_int_and_label(file
, &sf->antialias, "AntiAliased Text and Logo"))
return FALSE;
if (!read_int_and_label(file
, &sf->safe_title, "Safe Titling"))
return FALSE;
{
char *buf = file->line_buf;
/* Read inline of format NN NN NN Text Animation Mode */
if (!must_read_line(file))
return FALSE;
if (!next_number(file, &buf, &sf->animode))
return FALSE;
if (!next_number(file, &buf, &sf->aniframes))
return FALSE;
if (!next_number(file, &buf, &sf->anispeed))
return FALSE;
if (!verify_label(file, buf, "Text Animation Mode"))
return FALSE;
}
}
Boolean read_slide_style(Slide_style *sf, char *file_name)
/*
* Open slide style file and read it. Complain if there's
* a problem.
*/
{
int ok = FALSE;
Line_file file;
char buf[256];
if (line_file_open(&file, file_name, buf, sizeof(buf)))
{
ok = inside_read_slide_style(sf, &file);
line_file_close(&file);
}
return ok;
}
//-------------------------------------------------------------------------
// Some Paragraph oriented stuff - to read in blank line separated sections
// of a text file.
//-------------------------------------------------------------------------
typedef struct paragraph
{
char **lines;
int line_count;
int line_alloc;
int xmargin;
int xoff;
int yoff;
int font_width;
int font_height;
int title_height;
int in_item_dist;
Boolean line_token;
Boolean nopause;
char clip_name[PATH_SIZE];
} Paragraph;
Boolean init_paragraph(Paragraph *p)
/*
* Set up empty paragraph.
*/
{
p->line_alloc = 50;
p->line_count = 0;
p->xmargin = 0;
p->xoff = 0;
p->yoff = 0;
p->font_width = 0;
p->font_height = 0;
p->title_height = 0;
p->in_item_dist = 0;
p->line_token = FALSE;
p->nopause = FALSE;
strcpy(p->clip_name,"none");
if ((p->lines = need_memory(p->line_alloc * sizeof(char *))) == NULL)
{
return FALSE;
}
return TRUE;
}
void free_paragraph(Paragraph *p)
/*
* Free all dynamic memory associated with paragraph.
*/
{
int i;
if (p->lines != NULL)
{
for (i=0; i<p->line_count; ++i)
{
if (p->lines[i] != NULL)
free(p->lines[i]);
}
free(p->lines);
p->lines = NULL;
}
}
Boolean paragraph_add_line(Paragraph *p, char *line)
/*
* Add a line to paragraph.
*/
{
if (p->line_count < p->line_alloc)
{
if (p->line_token == FALSE)
{
if ((p->lines[p->line_count] = strdup(line)) == NULL)
{
Qtext("Not enough memory for %s", line);
return FALSE;
}
else
{
++p->line_count;
return TRUE;
}
}
else
{
return TRUE;
}
}
else
{
Qtext("Too many lines in paragraph");
return FALSE;
}
}
Boolean line_is_token(Paragraph *p, char *input, Line_file *file)
/*
* Check line for a token
*/
{
char *token;
char *token_line;
char *temp;
char *line;
int i;
Boolean another_token;
p->line_token = FALSE;
if ((token = strdup(input)) == NULL)
{
Qtext("Not enough memory for %s", input);
return FALSE;
}
if ((temp = strdup(input)) == NULL)
{
Qtext("Not enough memory for %s", input);
return FALSE;
}
if (next_string(file, &temp, token, strlen(temp)+1))
{
++temp;
if ((token_line = strdup(temp)) == NULL)
{
Qtext("Not enough memory for %s", temp);
return FALSE;
}
if (strlen(token_line) > 0)
token_line[strlen(token_line)-1] = EOS;
if (stricmp(token,"-nopause") == 0)
{
p->nopause = TRUE;
p->line_token = TRUE;
}
if (stricmp(token, "-i") == 0)
{
strcpy(p->clip_name, token_line);
p->line_token = TRUE;
}
if (stricmp(token, "-x") == 0)
{
strcpy(file->x_call, token_line);
p->line_token = TRUE;
}
if (stricmp(token, "-b") == 0)
{
if (strlen(token_line) > 0) //* Batch call must exist!
strcpy(file->bat_call, token_line);
p->line_token = TRUE;
}
return TRUE;
}
return FALSE;
}
Boolean read_paragraph(Paragraph *p, Line_file *file)
/*
* Read file until next blank line into paragraph.
*/
{
/* First skip over any blank lines. */
for (;;)
{
if (!read_line(file))
return FALSE;
if (skip_space(file->line_buf) != NULL)
break;
}
/* Now go to next blank line or EOF. */
for (;;)
{
if (!line_is_token(p, file->line_buf, file))
return TRUE;
if (!paragraph_add_line(p, file->line_buf))
return TRUE;
if (!read_line(file))
return TRUE;
if (skip_space(file->line_buf) == NULL)
return TRUE;
}
}
static Boolean init_and_read_paragraph(Paragraph *p, Line_file *lf)
/*
* Initialize and read a paragraph. Free things up and return FALSE
* if there's a problem.
*/
{
if (init_paragraph(p))
{
if (read_paragraph(p, lf))
{
return TRUE;
}
free_paragraph(p);
}
return FALSE;
}
//-------------------------------------------------------------------------
// File naming routines.
//-------------------------------------------------------------------------
static void batch_to_base_name(char *batch_name, char *base_name)
/*
* Convert the .bat file name to a base name to use as the start
* of the names for .scr and .flc files.
*/
{
char dev[4], dir[PATH_SIZE], file[10], suff[5];
fnsplit(batch_name, dev, dir, file, suff);
file[5] = 0; /* Leave room for number. */
sprintf(base_name, "%s%s%s", dev, dir, file);
}
static void base_to_script_name(char *base_name, char *script_name
, int script_num)
/*
* Go from path\xxxxx to path\xxxxxNNN.scr
*/
{
sprintf(script_name, "%s%03d.SCR", base_name, script_num);
}
static void base_name_to_slide_start(char *base_name
, char *slide_start, int slide_ix)
/*
* Go from path\xxxxx to path\xxxxxNN
*/
{
sprintf(slide_start, "%s%02d", base_name, slide_ix);
}
static void slide_flic_name(char *flic_name, char *slide_name, int line_ix)
/*
* Go from path\xxxxxNN to path\xxxxxNNa.FLC
*/
{
sprintf(flic_name, "%s%c.FLC", slide_name, 'A'+line_ix);
}
//-------------------------------------------------------------------------
// Drawing routines
//-------------------------------------------------------------------------
typedef struct
/* Keep track of the color registers we want to draw in
* (as opposed to the RGB values)
*/
{
int title;
int item;
int bullet;
} Drawing_colors;
void find_drawing_colors(Drawing_colors *dc, Slide_style *sf)
/*
* Find colors to draw slide in from RGB values in Slide_style.
*/
{
dc->title = ClosestColorInScreen(GetPicScreen()
, sf->title_color.r, sf->title_color.g, sf->title_color.b);
dc->item = ClosestColorInScreen(NULL
, sf->item_color.r, sf->item_color.g, sf->item_color.b);
dc->bullet = ClosestColorInScreen(NULL
, sf->bullet_color.r, sf->bullet_color.g, sf->bullet_color.b);
}
static int find_intermediate_value(double percent, int start, int end)
/*
* Return a color percent between start and end.
*/
{
int diff = end - start;
return (start + percent*diff);
}
static void find_intermediate_color(RGB *result, double percent
, RGB *start, RGB *end)
/*
* Put a color percent between start and end into result
*/
{
result->r = find_intermediate_value(percent, start->r, end->r);
result->g = find_intermediate_value(percent, start->g, end->g);
result->b = find_intermediate_value(percent, start->b, end->b);
}
static void ramp_range(RGB *start_color, RGB *stop_color)
/*
* Puts a color ramp into the current range.
*/
{
int *cluster;
int ccount;
int i;
double percent;
RGB intermediate;
Errcode err;
if ((err = GetCluster(&ccount, &cluster)) < Success)
Qerror(err, "Can't GetCluster");
else
{
for (i=0; i<ccount; ++i)
{
percent = (double)i/(double)(ccount-1);
find_intermediate_color(&intermediate, percent
, start_color, stop_color);
SetColorMap(cluster[i]
, intermediate.r, intermediate.g, intermediate.b);
}
free(cluster);
}
}
static void set_color_range(int start, int stop
, RGB *start_color, RGB *stop_color)
/*
* This puts the colors from start to stop into the cluster.
* Then it makes a gradient in those colors from start_color to
* stop_color.
*/
{
int *cluster;
int i;
int ccount = stop-start+1;
if ((cluster = need_memory(ccount * sizeof(int))) != NULL)
{
for (i=0; i<ccount; ++i)
{
cluster[i] = start+i;
}
SetCluster(ccount, cluster);
free(cluster);
}
ramp_range(start_color, stop_color);
}
static Boolean is_solid(char *name)
{
return stricmp(name, "solid") == 0;
}
static Boolean is_gradient(char *name)
{
return stricmp(name, "gradient") == 0;
}
static Errcode change_flic_size(int width, int height)
/*
* Check to see if current flic is width x height. If not do a
* resize reset to force it.
*/
{
int ow, oh;
GetSize(&ow, &oh);
if (ow != width || oh != height)
{
return ResizeReset(width, height);
}
else
return Success;
}
static Boolean preload_background(Slide_style *sf)
/*
* Draw the background into swap screen.
*/
{
char *name = sf->background_image;
RGB *col = &sf->background_color;
static RGB black = {0,0,0};
int phy_width, phy_height;
int back_color_index;
static struct optPos op;
GetPhysicalSize(&phy_width, &phy_height);
if (sf->safe_title == TRUE)
{
slide_width = phy_width*0.9;
slide_height = phy_height*0.9;
}
else
{
if ((phy_width > slide_width) || (phy_height > slide_height))
{
if (change_flic_size(phy_width, phy_height) < Success)
return FALSE;
slide_width = phy_width;
slide_height = phy_height;
}
}
SetFilled(TRUE);
if (is_solid(name))
{
if (sf->safe_title == TRUE)
{
if (change_flic_size(slide_width, slide_height) < Success)
return FALSE;
}
else
{
GetPhysicalSize(&phy_width, &phy_height);
if (change_flic_size(phy_width, phy_height) < Success)
return FALSE;
}
Clear();
back_color_index = ClosestColorInScreen(NULL, sf->background_color.r
, sf->background_color.g, sf->background_color.b);
SetColor(back_color_index);
SetInk("Opaque");
Box(0, 0, slide_width, slide_height);
}
else if (is_gradient(name))
{
if (sf->safe_title == TRUE)
{
if (change_flic_size(slide_width, slide_height) < Success)
return FALSE;
}
else
{
GetPhysicalSize(&phy_width, &phy_height);
if (change_flic_size(phy_width, phy_height) < Success)
return FALSE;
}
set_color_range(0, 63, &black, col);
SetInk("V Grad");
Box(0, 0, slide_width, slide_height);
}
else
{
if (sf->safe_title == TRUE) //* Shrink the visible screen by 90%
{
int cmap[256*3];
GetPhysicalSize(&phy_width, &phy_height);
if (change_flic_size(phy_width, phy_height) < Success)
return FALSE;
LoadPic(name);
GetScreenColorMap(GetPicScreen(), cmap);
OptClearPos();
OptDefaultCenters();
OptGetPos(&op);
op.bp = 90; //* new size to be 90% of original
op.bq = 100;
OptSetPos(&op);
OptSetElement(EL_SCREEN);
OptToFrame(1);
CelClip();
if (change_flic_size(slide_width, slide_height) < Success)
return FALSE;
SetScreenColorMap(GetPicScreen(), cmap);
CelMoveTo(slide_width/2, slide_height/2);
CelPaste();
}
else
{
LoadPic(name);
}
}
SwapClip();
return SwapExists();
}
static Boolean draw_clip(Paragraph *p)
/*
* Draw the clip
*/
{
int x,y,clipw,cliph;
if (stricmp(p->clip_name, "none") == 0)
return TRUE;
if (LoadCel(p->clip_name) >= Success)
{
GetScreenSize( GetCelScreen(), &clipw, &cliph);
x = clipw/2 + (slide_width - clipw)/2;
y = p->title_height + cliph/2 +
(slide_height - p->title_height - cliph)/2;
CelMoveTo(x, y);
SetInk("opaque");
CelPaste();
return TRUE;
}
else
{
Qtext("Could not load clip file:n\"%s\"", p->clip_name);
return FALSE;
}
}
static Boolean draw_logo(Slide_style *sf)
/*
* Draw the logo
*/
{
XY *pos;
int logow,logoh;
if (stricmp(sf->logo_image, "none") == 0)
return TRUE;
if (LoadCel(sf->logo_image) >= Success)
{
pos = &sf->logo_position;
GetScreenSize( GetCelScreen(), &logow, &logoh);
CelMoveTo(pos->x, pos->y);
SetInk("opaque");
CelPaste();
if (sf->antialias)
{
PicDirtied();
SetInk("unzag");
CelPaste();
}
return TRUE;
}
else
return FALSE;
}
static void set_shadow(int strength)
/*
* Set up ink, etc for shadow.
*/
{
SetInk("Dark");
SetInkStrength(strength);
}
enum bullet_type {BT_NONE, BT_CEL, BT_CIRCLE};
typedef struct
{
enum bullet_type type; /* Type of bullet. */
RGB bullet_color; /* Bullet Color. */
int width, height; /* Dimensions of bullet. */
int text_xoff; /* Space from center of bullet to where
* text starts */
} Bullet_data;
void find_bullet(Bullet_data *bd, Slide_style *sf, Paragraph *pb)
/*
* This will load the bullet into the Cel if possible
* otherwise complain and revert to the circle bullet.
* Returns type.
*/
{
if (stricmp(sf->bullet_image, "none") == 0)
{
bd->width = bd->height = 0;
bd->text_xoff = 0;
bd->type = BT_NONE;
}
else if (stricmp(sf->bullet_image, "circle") == 0)
{
bd->width = bd->height = pb->font_height/2;
bd->text_xoff = bd->width/2 + pb->font_width;
bd->type = BT_CIRCLE;
}
else
{
if (Success > LoadCel(sf->bullet_image))
{ /* On error revert to circle. */
strcpy(sf->bullet_image, "circle");
find_bullet(bd, sf, pb);
}
else
{
GetScreenSize(GetCelScreen(), &bd->width, &bd->height);
bd->text_xoff = bd->width/2 + pb->font_width;
bd->type = BT_CEL;
}
}
}
void draw_bullet(Slide_style *sf, Bullet_data *bd, int xoff, int yoff
, int color)
/*
* Draw a bullet centered at xoff, yoff. Should be called shortly after
* find_bullet() - or at least before you reload the cel.
*/
{
switch (bd->type)
{
case BT_CIRCLE:
{
int rad = bd->width/2;
set_shadow(50);
Circle(xoff+shadow_xoff, yoff+shadow_yoff, rad);
SetInk("Opaque");
SetColor(color);
Circle(xoff, yoff, rad);
if (sf->antialias)
{
PicDirtied();
SetInk("unzag");
Circle(xoff, yoff, rad);
}
}
break;
case BT_CEL:
CelMoveTo(xoff, yoff);
SetInk("Opaque");
CelPaste();
if (sf->antialias)
{
PicDirtied();
SetInk("unzag");
CelPaste();
}
break;
case BT_NONE:
default:
break;
}
}
static void draw_shadow_and_antialias(int x, int y, int w, int color
, int shadow_x, int shadow_y, char *string, Boolean antialias)
/*
* Draw text and it's drop shadow. Then antialias if desired.
*/
{
/* Draw drop-shadow. */
set_shadow(50);
WordWrap(x+shadow_x, y+shadow_y, w, slide_height, string);
/* Draw text proper. */
SetInk("Opaque");
SetColor(color);
WordWrap(x, y, w, slide_height, string);
/* Do anti-aliasing. */
if (antialias)
{
PicDirtied();
SetInk("unzag");
WordWrap(x, y, w, slide_height, string);
}
}
static int draw_still_text( int x_start, int y_start, int w, int text_color
, char *string, int justification, Boolean antialias)
/*
* Show text with a drop shadow. Returns the # of lines of text
* drawn.
*/
{
SetJustify(justification);
draw_shadow_and_antialias(x_start, y_start, w, text_color
, shadow_xoff, shadow_yoff, string, antialias);
return WordWrapCountLines(w, string);
}
typedef struct jiffy_timer
/* Structure to help us wait until a certain number of jiffies have passed */
{
int jiffy_count;
long start_millis;
} Jiffy_timer;
void start_jiffy_timer(Jiffy_timer *this, int jiffy_count)
/*
* Call this at start of time interval.
*/
{
this->jiffy_count = jiffy_count;
this->start_millis = Clock1000();
}
Boolean wait_jiffy_timer(Jiffy_timer *this)
/*
* Call this to wait until interval has passed.
* Return FALSE if escape key pressed in the meantime.
*/
{
long stop_millis = (this->jiffy_count * 1000L / 70) + this->start_millis;
int x,y,left,right,key;
while (stop_millis > Clock1000())
{
PollInput(&x,&y,&left,&right,&key);
if ((key&0xff) == ESCAPE_KEY)
return FALSE;
}
return TRUE;
}
typedef struct behind
/* Keep track of area behind animation. */
{
char *pixels;
int x, y;
int width, height;
} Behind;
Boolean init_behind(Behind *b, int x, int y, int width, int height)
/*
* Set up data structure to store a rectangular area of the screen
* and allocate memory buffer to hold pixels.
*/
{
b->width = width;
b->height = height;
b->x = x;
b->y = y;
if ((b->pixels = need_memory(width*height*PIXEL_SIZE)) == NULL)
return FALSE;
return TRUE;
}
Boolean save_behind(Behind *b)
/*
* Back up a portion of the screen.
*/
{
GetBlock(GetPicScreen(), b->pixels, b->x, b->y, b->width, b->height);
}
Boolean restore_behind(Behind *b)
/*
* Restore a portion of the screen.
*/
{
SetBlock(GetPicScreen(), b->pixels, b->x, b->y, b->width, b->height);
}
Boolean free_behind(Behind *b)
/*
* Free up pixel memory buffer.
*/
{
if (b->pixels != NULL)
{
free(b->pixels);
b->pixels = NULL;
}
}
static int draw_scroll_text( int x_start, int y_start, int w
, int shadow_x, int shadow_y
, int text_color, char *string, Boolean antialias
, int frame_count, int flic_speed, Boolean save)
/*
* Show text with a drop shadow. Returns the # of lines of text
* drawn.
*/
{
double dist; //* animation offset distance
double dx; //* incremental distance per frame
int nf; //* frame index
int line_count = WordWrapCountLines(w, string);
int ok = TRUE;
/* Calculate size of word-wrap box. */
w = slide_width*0.95 - x_start;
/* Draw text proper. */
SetJustify(0);
dist = slide_width - x_start;
dx = dist / frame_count;
if (save)
{
for(nf=0;nf<frame_count; nf++)
{
dist -= dx;
NextFrame();
draw_shadow_and_antialias(x_start+dist, y_start, w, text_color
, shadow_x, shadow_y, string, antialias);
}
}
else
{
Behind behind;
Jiffy_timer timer;
if (init_behind(&behind, x_start, y_start
, slide_width - x_start, line_count * FontHeight() + shadow_y))
{
save_behind(&behind);
for(nf=0;nf<frame_count; nf++)
{
start_jiffy_timer(&timer, flic_speed);
dist -= dx;
restore_behind(&behind);
draw_shadow_and_antialias(x_start+dist, y_start, w, text_color
, shadow_x, shadow_y, string, antialias);
if (!wait_jiffy_timer(&timer))
{
ok = FALSE;
break;
}
}
free_behind(&behind);
}
}
return ok;
}
static int draw_transparent_and_shadowed(int x, int y, int w, int color
, int shadow_x, int shadow_y
, char *string, Boolean antialias, int percent)
/*
* Draw transparent text and an even more transparent drop shadow.
*/
{
/* Draw shadow. */
set_shadow(percent/2);
WordWrap(x+shadow_x, y+shadow_y, w, slide_height, string);
SetInk("glass");
SetInkStrength(percent);
SetColor(color);
WordWrap(x, y, w, slide_height, string);
/* Do anti-aliasing. */
if (antialias)
{
PicDirtied();
SetInk("unzag");
WordWrap(x, y, w, slide_height, string);
}
}
static int draw_fade_text( int x_start, int y_start, int w
, int shadow_x, int shadow_y
, int text_color, char *string, Boolean antialias
, int frame_count, int flic_speed, Boolean save)
/*
* Draw text fading in. (Either to file or by preview.)
*/
{
double trans; //* ink strength for glass ink
double tx; //* ink strength increment per frame
int nf; //* frame index
int line_count = WordWrapCountLines(w, string);
Boolean ok = TRUE;
SetJustify(0);
tx = 100 / frame_count;
trans = 0;
if (save)
{
for(nf=0;nf<frame_count; nf++)
{
trans += tx;
NextFrame();
draw_transparent_and_shadowed(x_start, y_start, w, text_color
, shadow_x, shadow_y, string, antialias, trans);
}
}
else
{
Behind behind;
Jiffy_timer timer;
if (init_behind(&behind, x_start, y_start
, slide_width - x_start, line_count * FontHeight() + shadow_y))
{
save_behind(&behind);
for(nf=0;nf<frame_count; nf++)
{
start_jiffy_timer(&timer, flic_speed);
trans += tx;
restore_behind(&behind);
draw_transparent_and_shadowed(x_start, y_start, w, text_color
, shadow_x, shadow_y, string, antialias, trans);
if (!wait_jiffy_timer(&timer))
{
ok = FALSE;
break;
}
}
free_behind(&behind);
}
}
return ok;
}
static Boolean draw_still_items(Slide_style *sf, Drawing_colors *ci
, Paragraph *pi, Bullet_data *bi, Boolean save, char *base_name)
{
Boolean ok = TRUE;
int i;
int actual_lines;
char save_file[PATH_SIZE];
RGB *col = &sf->background_color;
int x,y,l,r,key;
static struct optPos op;
SetJustify(0);
for (i=1; i<=pi->line_count-1; ++i)
{
draw_bullet(sf, bi
, pi->xmargin, pi->yoff+pi->font_height/2, ci->bullet);
actual_lines = draw_still_text(pi->xoff, pi->yoff
, slide_width*0.95 - pi->xoff, ci->item, pi->lines[i]
, 0 , sf->antialias);
pi->yoff += pi->in_item_dist + actual_lines*pi->font_height;
}
if(save)
{
slide_flic_name(save_file, base_name, 0);
printf("Saving file %s to disk", save_file);
fprintf(script
, "%s -p 0 -t fadein color(%d,%d,%d) fadeout color(%d,%d,%d)\n"
, save_file
, col->r/2, col->g/2, col->b/2
, col->r/2, col->g/2, col->b/2);
if (SaveFlic(save_file) < Success)
ok = FALSE;
unprintf();
}
return ok;
}
static Boolean wait_for_escape()
/*
* Waits for next click. Returns TRUE if it was a keypress <esc>
*/
{
int x,y,left,right, key;
WaitClick(&x,&y,&left,&right,&key);
return (key&0xff) == ESCAPE_KEY;
}
static Boolean draw_anim_items(Slide_style *sf, Drawing_colors *ci
, Paragraph *pi, Bullet_data *bi, Boolean save, char *base_name)
/*
* Do drawing and possibly more of animated slide.
*/
{
int i = 0;
int actual_lines;
int item_count;
char save_file[PATH_SIZE];
RGB *col = &sf->background_color;
static struct optPos op;
int item_width = slide_width * 0.95 - pi->xoff;
item_count = pi->line_count;
if(save)
{
slide_flic_name(save_file, base_name, 0);
printf("Saving %s to disk",save_file);
if (SaveFlic(save_file) < Success)
return FALSE;
unprintf();
if((item_count == 1) && (pi->nopause == TRUE))
{
fprintf(script
, "%s -p 1 -t fadein color(%d,%d,%d) fadeout color(%d,%d,%d)\n"
, save_file
, col->r/2, col->g/2, col->b/2
, col->r/2, col->g/2, col->b/2);
}
else if((item_count == 1) && (pi->nopause == FALSE))
{
fprintf(script
, "%s -p 0 -t fadein color(%d,%d,%d) fadeout color(%d,%d,%d)\n"
, save_file
, col->r/2, col->g/2, col->b/2
, col->r/2, col->g/2, col->b/2);
}
else if((item_count > 1) && (pi->nopause == TRUE))
{
fprintf(script
, "%s -p 1 -t fadein color(%d,%d,%d) \n"
, save_file
, col->r/2, col->g/2, col->b/2);
}
else if((item_count > 1) && (pi->nopause == FALSE))
{
fprintf(script
, "%s -p 0 -t fadein color(%d,%d,%d)\n"
, save_file
, col->r/2, col->g/2, col->b/2);
}
}
for (i=1; i<=item_count-1; i++)
{
draw_bullet(sf, bi
, pi->xmargin, pi->yoff+pi->font_height/2, ci->bullet);
if (save)
InsertFrames(sf->aniframes);
if(sf->animode == AM_SCROLL)
{
if (!draw_scroll_text(pi->xoff, pi->yoff, item_width
, shadow_xoff, shadow_yoff, ci->item
, pi->lines[i], sf->antialias, sf->aniframes, sf->anispeed, save))
return FALSE;
}
else if(sf->animode == AM_FADE)
{
if (!draw_fade_text(pi->xoff, pi->yoff, item_width
, shadow_xoff, shadow_yoff, ci->item
, pi->lines[i], sf->antialias, sf->aniframes, sf->anispeed, save))
return FALSE;
}
actual_lines = WordWrapCountLines(item_width, pi->lines[i]);
pi->yoff += pi->in_item_dist + actual_lines*pi->font_height;
if (save)
{
slide_flic_name(save_file, base_name, i);
printf("Saving flic %s to disk",save_file);
if (SaveFlic(save_file) < Success)
return FALSE;
NextFrame();
DeleteFrames(sf->aniframes); //* delete previous frames
BackFrame(); //* now return to the last frame
if(i == item_count-1)
{
fprintf(script
, "%s -p 0 -s %i -t fadeout color(%d,%d,%d)\n"
, save_file, sf->anispeed
, col->r/2, col->g/2, col->b/2);
}
else
{
if (pi->nopause)
{
fprintf(script
, "%s -s %i \n"
, save_file, sf->anispeed);
}
else
{
fprintf(script
, "%s -p 0 -s %i \n"
, save_file, sf->anispeed);
}
}
unprintf();
}
else if (!pi->nopause && i != item_count - 1)
{
if (wait_for_escape())
{
unprintf();
return FALSE;
}
unprintf();
}
}
return TRUE;
}
static Boolean draw_one_slide(Slide_style *sf, Line_file *file
, enum AnimMode mode, Boolean save, char *base_name)
/*
* This draws a paragraph according to the slide style.
* Calculates all the x,y positions to draw everything, and draws
* the standard slide, with the title.
*/
{
Paragraph p;
Boolean ok = FALSE;
Drawing_colors colors;
Bullet_data b;
int title_font_height;
int item_total_lines;
int empty_height;
int i;
/*
* Load in next paragraph from input file and
* display it.
*/
find_drawing_colors(&colors, sf);
if (init_and_read_paragraph(&p, file))
{
if (p.line_count >= 1)
{
/* Draw background. */
CopyScreen(GetSwapScreen(), GetPicScreen());
PicDirtied ();
/* Draw title. */
set_font_style(&sf->title_font);
title_font_height = FontHeight();
p.title_height
= WordWrapCountLines(get_title_width(sf), p.lines[0]);
p.title_height *=title_font_height;
p.title_height +=sf->title_position.y;
draw_clip(&p);
draw_logo(sf);
draw_still_text(sf->title_position.x
, sf->title_position.y, get_title_width(sf), colors.title
, p.lines[0], sf->title_justification, sf->antialias);
set_font_style(&sf->item_font);
p.font_height = FontHeight();
p.font_width = StringWidth("x");
p.xmargin = slide_width/10;
find_bullet(&b, sf, &p);
/* figure empty_height - the amount of the screen that has no
* text or title in it. */
p.xoff = p.xmargin + b.text_xoff; /* Left edge of text. */
item_total_lines = 0;
for (i=1; i<=p.line_count-1; ++i)
{
item_total_lines
+= WordWrapCountLines(slide_width*0.95-p.xoff, p.lines[i]);
}
empty_height = (slide_height*0.95) - p.title_height
- item_total_lines * p.font_height;
/* Calculate the inter_item_distance and where to start item
* text vertically.
* We'll leave a margin 1/3 again the space between items
* between the title and the items. */
p.in_item_dist = (empty_height)/(p.line_count+1);
p.yoff = p.title_height
+ (empty_height - p.in_item_dist*(p.line_count-2))/3;
switch(mode)
{
case AM_STILL:
if(!draw_still_items(sf
, &colors, &p, &b, save, base_name))
return FALSE;
break;
case AM_SCROLL:
if(!draw_anim_items(sf
, &colors, &p, &b, save, base_name))
return FALSE;
break;
case AM_FADE:
if(!draw_anim_items(sf
, &colors, &p, &b, save, base_name))
return FALSE;
break;
}
}
ok = TRUE;
free_paragraph(&p);
}
return ok;
}
//-------------------------------------------------------------------------
// Internal routines.
//-------------------------------------------------------------------------
static Boolean make_sample_file(char *sample_file_name, Slide_style *sf)
/*
* Make up a little text file that's got a sample of our stuff.
*/
{
FILE *f;
char name_only[PATH_SIZE];
if ((f = must_open(sample_file_name, "w")) == NULL)
return FALSE;
fprintf(f, "-nopause\n");
fprintf(f,"Example Slide\n");
file_name_only(sf->title_font.name, name_only);
fprintf(f,"Title Font is %s\n", name_only);
file_name_only(sf->item_font.name, name_only);
fprintf(f,"Item Font is %s\n", name_only);
switch(sf->animode)
{
case AM_STILL:
fprintf(f,"Output will be still images \n");
break;
case AM_SCROLL:
fprintf(f, "Items will scroll across %i frames, at %i jiffies \n"
, sf->aniframes, sf->anispeed);
break;
case AM_FADE:
fprintf(f, "Items will fade through %i frames, at %i jiffies \n"
, sf->aniframes, sf->anispeed);
break;
default:
fprintf(f,"Output will be still images \n");
break;
}
fprintf(f, "Output Anti-aliasing is %s \n", off_on[sf->antialias]);
fclose(f);
return TRUE;
}
static Boolean display_sample(Slide_style *sf)
/*
* Display current slide style sample on screen.
*/
{
Line_file file;
char *temp_name = "=:show'em.tmp";
char buf[256];
if (make_sample_file(temp_name, sf))
{
if (line_file_open(&file, temp_name, buf, sizeof(buf)))
{
draw_one_slide(sf, &file, AM_STILL, FALSE, NULL);
line_file_close(&file);
}
DosDelete(temp_name);
}
}
static void init_style(Slide_style *sf)
/*
* Read in style. If there's no style file or some other problem
* then use default style.
*/
{
set_default_style(sf);
if (DosExists(persistant_style))
read_slide_style(sf, persistant_style);
}
static Boolean list_slide_files(char *slide_start_name
, enum AnimMode animode, Paragraph *slide_text, Paragraph *out)
{
char flic_name[PATH_SIZE];
int i;
for (i=0; i<slide_text->line_count; ++i)
{
slide_flic_name(flic_name, slide_start_name, i);
if (!paragraph_add_line(out, flic_name))
return FALSE;
if (animode == AM_STILL)
return TRUE;
}
return TRUE;
}
static Boolean list_showem_files(Slide_style *sf, Line_file *in
, char *bat_name, Paragraph *out)
/*
* This puts a list of all files that will be created from "bat_name"
* in the out paragraph.
*/
{
char base_name[PATH_SIZE];
char script_name[PATH_SIZE];
char slide_start[PATH_SIZE];
int script_num = 0;
int slide_ix;
Paragraph p;
Boolean ok;
if (!paragraph_add_line(out, bat_name))
return FALSE;
batch_to_base_name(bat_name, base_name);
base_to_script_name(base_name, script_name, script_num);
if (!paragraph_add_line(out, script_name))
return FALSE;
for (slide_ix = 0; ; ++slide_ix)
{
strcpy(in->bat_call, "none");
base_name_to_slide_start(base_name, slide_start, slide_ix);
if (!init_and_read_paragraph(&p, in))
return TRUE;
ok = TRUE;
if (strcmp(in->bat_call, "none") != 0)
{
script_num = script_num +1;
base_to_script_name(base_name, script_name, script_num);
ok = paragraph_add_line(out, script_name);
}
if (ok)
{
ok = list_slide_files(slide_start, sf->animode, &p, out);
free_paragraph(&p);
}
if (!ok)
return FALSE;
}
}
static Boolean overwrite_list_ok(Paragraph *p)
/*
* Bring up a scroller containing the paragraph and ask if it's ok to
* overwrite it.
*/
{
int pos = 0;
int choice = 0;
int i;
char *listbuttons[] = {"Yes", NULL, "No"};
return (Qscroll(&choice, p->lines, p->line_count, &pos, listbuttons
, "Overwrite the following files?") == 1);
}
static Boolean make_overwrite_list(Paragraph *all, Paragraph *overwrites)
{
int i;
char *file_name;
for (i=0; i<all->line_count; ++i)
{
file_name = all->lines[i];
if (DosExists(file_name))
{
if (!paragraph_add_line(overwrites, file_name))
return FALSE;
}
}
return TRUE;
}
static Boolean overwrite_files_ok(Slide_style *sf, char *batch_name)
{
Line_file lfile;
char buf[256];
Boolean ok = FALSE;
Paragraph file_list;
Paragraph overwrite_list;
if (line_file_open(&lfile, persistant_text, buf, sizeof(buf)))
{
if (init_paragraph(&file_list))
{
if (list_showem_files(sf, &lfile, batch_name, &file_list))
{
if (init_paragraph(&overwrite_list))
{
if (make_overwrite_list(&file_list, &overwrite_list))
{
if (overwrite_list.line_count == 0)
ok = TRUE;
else
ok = overwrite_list_ok(&overwrite_list);
}
free_paragraph(&overwrite_list);
}
}
free_paragraph(&file_list);
}
line_file_close(&lfile);
}
return ok;
}
static Boolean render_slides(Slide_style *sf, char *batch_name)
/*
* Open up text file and go make as many slides as there are
* paragraphs. Write out commands to script too.
*/
{
Boolean ok = TRUE;
int i;
Line_file lfile;
char buf[256];
FILE *batch;
int script_num = 0;
char script_name[PATH_SIZE];
char slide_name[PATH_SIZE];
char base_name[PATH_SIZE];
static char temp_dir[PATH_SIZE];
static char ani_dir[PATH_SIZE];
Boolean script_empty;
ok = FALSE;
/* Figure out base name of numbered flics. Will convert something
* like C:\ANI\1STQUARTR.SCR into C:\ANI\1STQ */
batch_to_base_name(batch_name, base_name);
GetDir(ani_dir);
GetResourceDir(temp_dir);
SetDir(temp_dir);
SetDir("..");
strcpy(temp_dir, ani_dir);
GetDir(ani_dir);
SetDir(temp_dir);
if (line_file_open(&lfile, persistant_text, buf, sizeof(buf)))
{
if ((batch = must_open(batch_name, "w")) != NULL)
{
fprintf(batch, "@echo off \n");
base_to_script_name(base_name, script_name, script_num);
if ((script = must_open(script_name, "w")) != NULL)
{
for (i=0; ; ++i) /* Keep count. */
{
strcpy(lfile.x_call, "none");
strcpy(lfile.bat_call, "none");
base_name_to_slide_start(base_name, slide_name, i);
if(draw_one_slide(sf
, &lfile, sf->animode, TRUE, slide_name))
{
if (strcmp(lfile.x_call, "none") != 0)
{
fprintf(script, "%s \n", lfile.x_call);
strcpy(lfile.x_call, "none");
}
if (strcmp(lfile.bat_call, "none") != 0)
{
if (ftell(script) != 0)
{
fprintf(script,"Exittodos \n");
fprintf(batch
, "%sANIPLAY -AUTO -CFG %sAA.CFG %s \n"
, ani_dir, ani_dir, script_name);
}
fprintf(batch,"%s \n",lfile.bat_call);
fclose(script);
script_num = script_num +1;
base_to_script_name(base_name, script_name
, script_num);
if((script = must_open(script_name,"w")) == NULL)
{
ok = FALSE;
break;
}
strcpy(lfile.bat_call, "none");
}
}
else
{
ok = TRUE;
break;
}
}
script_empty = (ftell(script) == 0);
fclose(script);
if(!script_empty)
{
fprintf(batch,"%sANIPLAY -AUTO -CFG %sAA.CFG %s \n",
ani_dir, ani_dir, script_name);
}
else
{
DosDelete(script_name);
}
}
fclose(batch);
}
line_file_close(&lfile);
}
return ok;
}
static Boolean preview_slides(Slide_style *sf)
/*
* Put up one slide after the other, pausing for a key press or
* mouse click between each one.
*/
{
Line_file lfile;
char buf[256];
Boolean ok = FALSE;
Boolean go_on;
int i;
int x,y,l,r,key;
HideCursor();
if (line_file_open(&lfile, persistant_text, buf, sizeof(buf)))
{
printf("Press any key or click to continue, escape to abort.");
for (i=0; ; ++i) /* Keep count. */
{
strcpy(lfile.x_call, "none");
strcpy(lfile.bat_call, "none");
if (!draw_one_slide(sf, &lfile, sf->animode, FALSE, NULL))
break;
else
ok = TRUE;
if (strcmp(lfile.x_call, "none") != 0)
Qtext("\"%s\"\n\nwill be written to the script."
, lfile.x_call);
else if (strcmp(lfile.bat_call, "none") != 0)
Qtext("\"%s\"\n\nwill be written to the batch file."
, lfile.bat_call);
else
{
if (wait_for_escape())
{
unprintf();
break;
}
}
unprintf();
}
line_file_close(&lfile);
}
ShowCursor();
return ok;
}
Boolean save_text(char *file_name)
/*
* Copy temp text file to a real file.
*/
{
text_changed = FALSE;
return copy_file(persistant_text, file_name);
}
Boolean qsave_text()
/*
* Bring up file requestor to save text file.
*/
{
Boolean ok = FALSE;
char name_buf[PATH_SIZE];
strcpy(name_buf, text_file_name);
if (Qfile(".TXT", "Save"
, name_buf, name_buf, TRUE, "Save Slide Text File"))
{
/* If it's the same as it was last loaded/saved just
* save it. */
if (text_named && (stricmp(text_file_name, name_buf) == 0))
{
save_text(name_buf);
ok = TRUE;
}
/* If it's a new name make sure they aren't overwriting
* something. */
else if (overwrite_ok(name_buf))
{
save_text(name_buf);
ok = TRUE;
}
text_named = TRUE;
strcpy(text_file_name, name_buf);
}
return ok;
}
Boolean insure_text(char *prompt_string)
/*
* Check to see if text has changed. If it has prompt user to save it.
* Note that prompt string should contain a %s where you want text_file_name
* to appear.
*/
{
char *buttons[] = {"Yes", "No", "Cancel",};
int choice;
if (!text_changed)
return TRUE;
choice = Qchoice(buttons, Array_els(buttons), prompt_string, text_file_name);
switch (choice)
{
case 1: /* Yes */
if (text_named)
return save_text(text_file_name);
else /* Check for overwrite if it's "unnamed.txt" */
{
if (!overwrite_ok(text_file_name))
return FALSE;
save_text(text_file_name);
}
case 2: /* No */
return TRUE;
default: /* Cancel */
return FALSE;
}
}
//-------------------------------------------------------------------------
// Routines that interact with User
//-------------------------------------------------------------------------
Boolean css_menu(Slide_style *sf)
/*
* Interpret the create slide show menu.
*/
{
int choice;
static int cursor_pos, line_pos;
static char bat_name[PATH_SIZE] = "show'em.scr";
short css_flags[Array_els(css_choices)];
for (;;)
{
memset(css_flags, 0, sizeof(css_flags));
if (!DosExists(persistant_text))
{
css_flags[CSS_RENDER] = css_flags[CSS_NEW]
= css_flags[CSS_PREVIEW] = css_flags[CSS_SAVE] = QMF_DISABLED;
}
choice = QmenuWithFlags(css_choices, Array_els(css_choices)
, css_flags, css_header);
switch(choice)
{
case CSS_HELP:
multi_screen_help(css_help, Array_els(css_help));
break;
case CSS_EDIT:
QeditFile(persistant_text, &cursor_pos, &line_pos);
text_changed = TRUE;
break;
case CSS_LOAD:
if (insure_text("Save %s before loading?"))
{
if (Qfile(".TXT", "Load", text_file_name, text_file_name
, FALSE, "Load Slide Text File"))
{
copy_file(text_file_name, persistant_text);
text_changed = FALSE;
text_named = TRUE;
}
}
break;
case CSS_SAVE:
qsave_text();
break;
case CSS_NEW:
{
if (insure_text("Save %s before starting new text?"))
{
DosDelete(persistant_text);
text_named = text_changed = FALSE;
strcpy(text_file_name, UNTITLED_TEXT);
}
}
break;
case CSS_PREVIEW:
preview_slides(sf);
break;
case CSS_RENDER:
if (Qfile(".BAT", "Save", bat_name, bat_name
, TRUE, "Render slides?"))
{
if (overwrite_files_ok(sf, bat_name))
{
if (render_slides(sf, bat_name))
return FALSE; /* Get out of program! */
}
}
break;
default:
return TRUE;
}
}
}
Boolean load_new_font(Font_style *fs)
/*
* Load font and record the name and size.
*/
{
Font_style new_style;
char full_font_name[PATH_SIZE];
/* Load up the current selection */
set_font_style(fs);
/* Go to font requestor. */
Qfont();
get_font_style(&new_style);
/* Return whether it's a new one */
if (memcmp(fs, &new_style, sizeof(new_style)) != 0)
{
memcpy(fs, &new_style, sizeof(*fs));
return TRUE;
}
else
return FALSE;
}
void title_menu(Slide_style *sf)
/*
* Interpret title menu
*/
{
int choice;
int just_choice;
Boolean is_changed;
int color;
int x,y,w,h;
for (;;)
{
is_changed = FALSE;
choice = Qmenu(title_choices, Array_els(title_choices), title_header);
switch(choice)
{
case TITLE_COLOR:
if ((color = Qcolor()) >= Success)
{
translate_to_rgb(color, &sf->title_color);
is_changed = TRUE;
}
break;
case TITLE_POS:
TitleSetText("Example Slide");
set_font_style(&sf->title_font);
SetJustify(sf->title_justification);
TitleSetPosition(sf->title_position.x, sf->title_position.y
, get_title_width(sf), FontHeight());
TitleEdit();
TitleGetPosition(&x,&y,&w,&h);
if (x != sf->title_position.x || y != sf->title_position.y)
{
sf->title_position.x = x;
sf->title_position.y = y;
is_changed = TRUE;
}
break;
case TITLE_JUST:
if (just_choice = Qmenu(title_just_choices
, Array_els(title_just_choices)
, title_just_header));
if (just_choice-1 != sf->title_justification
&& just_choice != 0)
{
sf->title_justification = just_choice-1;
is_changed = TRUE;
}
break;
case TITLE_FONT:
is_changed = load_new_font(&sf->title_font);
break;
default:
return;
}
if (is_changed)
display_sample(sf);
}
}
void item_menu(Slide_style *sf)
/*
* Interpret item menu
*/
{
int choice;
Boolean is_changed;
int color;
for (;;)
{
choice = Qmenu(item_choices, Array_els(item_choices), item_header);
switch(choice)
{
case ITEM_COLOR:
if ((color = Qcolor()) >= Success)
{
translate_to_rgb(color, &sf->item_color);
is_changed = TRUE;
}
break;
case ITEM_FONT:
is_changed = load_new_font(&sf->item_font);
break;
default:
return;
}
if (is_changed)
display_sample(sf);
}
}
void bullet_menu(Slide_style *sf)
/*
* Interpret bullet menu
*/
{
int choice;
Boolean is_changed;
char header[80];
char file_name[32];
char bullet_name[PATH_SIZE];
int color;
strcpy(bullet_name, sf->bullet_image);
for (;;)
{
file_name_only(sf->bullet_image, file_name);
sprintf(header, "%s (%s)", bullet_header, file_name);
is_changed = FALSE;
choice = Qmenu(bullet_choices, Array_els(bullet_choices), header);
switch(choice)
{
case BULLET_COLOR:
if ((color = Qcolor()) >= Success)
{
translate_to_rgb(color, &sf->bullet_color);
strcpy(sf->bullet_image, "circle");
is_changed = TRUE;
}
break;
case BULLET_CIRCLE:
if (!stricmp(sf->bullet_image, "circle") == 0)
{
strcpy(sf->bullet_image, "circle");
is_changed = TRUE;
}
break;
case BULLET_USE_CEL:
if (Qfile(".CEL;.FL?", "Load"
, bullet_name, bullet_name
, FALSE, "Load Bullet Image"))
if (LoadCel(bullet_name) >= Success)
{
strcpy(sf->bullet_image, bullet_name);
is_changed = TRUE;
}
break;
case BULLET_NONE:
if (!stricmp(sf->bullet_image, "none") == 0)
{
strcpy(sf->bullet_image, "none");
is_changed = TRUE;
}
break;
default:
return;
}
if (is_changed)
display_sample(sf);
}
}
void background_menu(Slide_style *sf)
/*
* Interpret background menu.
*/
{
int choice;
char file_name[32];
char header[80];
int color;
char background_name[PATH_SIZE];
Boolean is_changed;
strcpy(background_name, sf->background_image);
for (;;)
{
file_name_only(sf->background_image, file_name);
sprintf(header, "%s (%s)", background_header, file_name);
is_changed = FALSE;
choice = Qmenu(background_choices
, Array_els(background_choices), header);
switch(choice)
{
case BACKGROUND_GET_COLOR:
if ((color = Qcolor()) >= Success)
{
translate_to_rgb(color, &sf->background_color);
if (is_solid(sf->background_image)
|| is_gradient(sf->background_image))
is_changed = TRUE;
}
break;
case BACKGROUND_SOLID:
if (!is_solid(sf->background_image))
{
strcpy(sf->background_image, "solid");
is_changed = TRUE;
}
break;
case BACKGROUND_GRADIENT:
if (!is_gradient(sf->background_image))
{
strcpy(sf->background_image, "gradient");
is_changed = TRUE;
}
break;
case BACKGROUND_USE_PIC:
if (Qfile(".GIF;.FL?;.PCX", "Load"
, background_name, background_name
, FALSE, "Load Background Image"))
{
if (LoadPic(background_name) >= Success)
{
strcpy(sf->background_image, background_name);
SwapClip();
display_sample(sf);
}
}
break;
default:
return;
}
if (is_changed)
{
preload_background(sf);
display_sample(sf);
}
}
}
void logo_menu(Slide_style *sf)
/*
* Interpret logo menu
*/
{
int choice;
Boolean is_changed;
char header[80];
char file_name[32];
char logo_name[PATH_SIZE];
int choice_count;
strcpy(logo_name, sf->logo_image);
for (;;)
{
file_name_only(sf->logo_image, file_name);
sprintf(header, "%s (%s)", logo_header, file_name);
is_changed = FALSE;
choice = Qmenu(logo_choices, Array_els(logo_choices), header);
switch(choice)
{
case LOGO_USE_CEL:
if (Qfile(".CEL;.FL?", "Load"
, logo_name, logo_name
, FALSE, "Load Logo Image"))
{
if (LoadCel(logo_name) >= Success)
{
strcpy(sf->logo_image, logo_name);
is_changed = TRUE;
}
}
break;
case LOGO_POSITION:
{
if (stricmp(sf->logo_image, "none") != 0)
{
if (LoadCel(sf->logo_image) >= Success)
{
int x,y,w,h;
GetScreenSize(GetCelScreen(), &w, &h);
x = sf->logo_position.x - w/2;
y = sf->logo_position.y - h/2;
if (DragBox(&x,&y,&w,&h))
{
sf->logo_position.x = x + w/2;
sf->logo_position.y = y + h/2;
is_changed = TRUE;
}
}
}
}
break;
case LOGO_NONE:
if (!stricmp(sf->logo_image, "none") == 0)
{
strcpy(sf->logo_image, "none");
is_changed = TRUE;
}
break;
default:
return;
}
if (is_changed)
display_sample(sf);
}
}
static Boolean ani_settings(Slide_style *sf)
{
Boolean ok = FALSE;
int i;
int x;
char prompt[80];
sprintf(prompt,"Select number of frames per item, currently %i"
, sf->aniframes);
i = sf->aniframes;
if (!Qnumber(&i, 1, 100, prompt))
return FALSE;
if(i < 100 || i > 0)
{
sprintf(prompt, "Select playback speed, currently %i"
, sf->anispeed);
x = sf->anispeed;
Qnumber(&x, 0, 100, prompt);
if(x > 0 || x < 100)
{
sf->aniframes = i;
sf->anispeed = x;
ok = TRUE;
}
else
Qtext("Speed must be between 1, and 100");
}
else
Qtext("Frames per item must be between 1, and 100");
return ok;
}
void out_menu(Slide_style *sf)
/*
* Interpret output menu.
*/
{
int choice;
char anti_line[40];
char safe_line[40];
Boolean is_changed = FALSE;
short out_flags[Array_els(out_choices)];
int i;
for (;;)
{
/* First set up the asterisks in the menu. */
memset(out_flags, 0, sizeof(out_flags)); /* Clear flags */
if (sf->antialias)
out_flags[OUT_ANTIALIAS] = QMF_ASTERISK;
if (sf->safe_title)
out_flags[OUT_SAFE_TITLE] = QMF_ASTERISK;
switch (sf->animode)
{
case AM_STILL:
out_flags[OUT_STILL] = QMF_ASTERISK;
break;
case AM_SCROLL:
out_flags[OUT_SCROLL] = QMF_ASTERISK;
break;
case AM_FADE:
out_flags[OUT_FADE] = QMF_ASTERISK;
break;
}
choice = QmenuWithFlags(out_choices, Array_els(out_choices)
, out_flags, out_header);
switch(choice)
{
case OUT_HELP:
Qtext(out_help1);
break;
case OUT_STILL:
if(!sf->animode == AM_STILL)
{
sf->animode = AM_STILL;
display_sample(sf);
}
break;
case OUT_SCROLL:
if(!sf->animode == AM_SCROLL || (ani_settings(sf)))
{
sf->animode = AM_SCROLL;
display_sample(sf);
}
break;
case OUT_FADE:
if(!sf->animode == AM_FADE || (ani_settings(sf)))
{
sf->animode = AM_FADE;
display_sample(sf);
}
break;
case OUT_ANTIALIAS:
sf->antialias = !sf->antialias;
display_sample(sf);
break;
case OUT_SAFE_TITLE:
sf->safe_title = !sf->safe_title;
preload_background(sf);
display_sample(sf);
break;
case OUT_PREVIEW:
preview_slides(sf);
break;
default:
return;
}
}
return;
}
void ssf_menu(Slide_style *sf)
/*
* Set Slide Style menu.
*/
{
int choice;
static char file_name[PATH_SIZE] = "show'em.sss";
char anti_line[40];
for (;;)
{
choice = Qmenu(ssf_choices, Array_els(ssf_choices), ssf_header);
switch(choice)
{
case SSF_HELP:
Qtext(ssf_help);
break;
case SSF_TITLE:
title_menu(sf);
break;
case SSF_ITEMS:
item_menu(sf);
break;
case SSF_BULLET:
bullet_menu(sf);
break;
case SSF_BACKGROUND:
background_menu(sf);
break;
case SSF_LOGO:
logo_menu(sf);
break;
case SSF_OUTPUT:
out_menu(sf);
break;
case SSF_LOAD:
if (Qfile(".SSS", "Load", file_name, file_name
, TRUE, "Load Show'em Slide Style"))
{
read_slide_style(sf, file_name);
preload_background(sf);
display_sample(sf);
}
break;
case SSF_SAVE:
if (Qfile(".SSS", "Save", file_name, file_name
, TRUE, "Save Show'em Slide Style"))
if (overwrite_ok(file_name))
if (!write_slide_style(sf, file_name))
Qtext("Could not save Style %s", file_name);
break;
default:
return;
}
}
}
void mm_menu(Slide_style *sf)
/*
* Interpret the top level menu.
*/
{
int choice;
for (;;)
{
choice = Qmenu(mm_choices, Array_els(mm_choices), mm_header);
switch(choice)
{
case MAIN_HELP:
multi_screen_help(mm_help, Array_els(mm_help));
break;
case MAIN_CREATE:
if (!css_menu(sf))
return;
break;
case MAIN_FORMAT:
ssf_menu(sf);
break;
default:
return;
}
}
}
main()
{
Slide_style style;
if (ignore_changes())
{
SetAbort(FALSE);
load_persistant();
GetSize(&slide_width, &slide_height);
shadow_xoff = slide_width/200;
shadow_yoff = slide_height/150;
SetFrameCount(1);
init_style(&style);
if (preload_background(&style))
{
display_sample(&style);
mm_menu(&style);
write_slide_style(&style, persistant_style);
save_persistant();
}
SwapRelease();
}
}